package com.bestom.videoplay.activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.storage.StorageManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.VideoView;

import com.bestom.videoplay.MediaApplication;
import com.bestom.videoplay.R;
import com.bestom.videoplay.beans.CommandBean;

import com.bestom.videoplay.callback.ScanCallback;
import com.bestom.videoplay.callback.SurfaceCallback;
import com.bestom.videoplay.listener.MediaPlayerListener;
import com.bestom.videoplay.receiver.ScreenReceiver;
import com.bestom.videoplay.service.VideoPlayService;
import com.bestom.videoplay.util.DocumentsUtils;
import com.bestom.videoplay.util.GetVideoFileUtil;
import com.bestom.videoplay.util.ToastUtil;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private static MediaPlayer mediaPlayer;
    private MediaController controller;

    private VideoView video_view;
    private LinearLayout fileSetting;
    private LinearLayout fileManage;
    private LinearLayout setting;
    private static MainActivity instance = null;

    public static MainActivity getInstance() {
        if (instance == null) instance = new MainActivity();
        return instance;
    }

    // 要申请的权限
    private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_COARSE_LOCATION};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setNavigationBarVisible(this, true);
        border = getResources().getDrawable(R.drawable.boder);
        noBorder = getResources().getDrawable(R.drawable.no_boder);
        mediaPlayer = new MediaPlayer();
        controller = new MediaController(this);
        controller.setAnchorView(findViewById(R.id.root));
        MediaApplication.getApplication().setMediaPlayer(mediaPlayer);
        bindService(new Intent(this, VideoPlayService.class), mServiceConnection, BIND_AUTO_CREATE);
        mBluetoothAdapter = initBluetoothAdapter();
        MediaApplication.getApplication().setmBluetoothAdapter(mBluetoothAdapter);
        // 版本判断。当手机系统大于 23 时，才有必要去判断权限是否获取
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 检查该权限是否已经获取
            int i = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[0]);
            int l = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[1]);
            int m = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[2]);
            // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
            if (i != PackageManager.PERMISSION_GRANTED && l != PackageManager.PERMISSION_GRANTED && m != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, permissions, 123);
            } else setTimer();
        }

        fileMap = new HashMap<>();
        initSurfaceView();
        titlePath = getSecondaryStoragePath() + "/Movies/";
        localFilePath = "/data/data/" + getPackageName() + "/files/codeValue.txt";
        readTxtFile();

        // 蓝牙笔对应数据接收广播
        IntentFilter filter = new IntentFilter();
        filter.addAction("characteristic");
        filter.addAction("connect");
        registerReceiver(characteristicReceiver, filter);

        // 开关机、息亮屏广播
        ScreenReceiver screenReceiver = new ScreenReceiver();
        IntentFilter screenFilter = new IntentFilter();
        // 添加要注册的action
        screenFilter.addAction("android.intent.action.SCREEN_OFF");
        screenFilter.addAction("android.intent.action.SCREEN_ON");
        screenFilter.addAction("android.intent.action.ACTION_SHUTDOWN");
        screenFilter.addAction("android.intent.action.BOOT_COMPLETED");
        // 动态注册广播接收者
        registerReceiver(screenReceiver, screenFilter);
    }

    private static HashMap<String, String> fileMap;
    private static String localFilePath;

    public void readTxtFile() {

        //打开文件
        File sdFile = new File(titlePath + "codeValue.txt");
        Log.d(TAG, "sdFile --->" + sdFile.exists());

        if (sdFile.exists()) {
            File file = new File(localFilePath);

            try {
                File fileParent = file.getParentFile();
                if (!fileParent.exists()) {
                    fileParent.mkdirs();
                }
                if (file.exists()) {
                    boolean delete = file.delete();
                    Log.d(TAG, "delete is -->" + delete + "file.exists() ?--->" + file.exists());
                    file.createNewFile();
                }

                OutputStream os = new FileOutputStream(file);
                OutputStreamWriter osw = new OutputStreamWriter(os);
                BufferedWriter bw = new BufferedWriter(osw);

                InputStream is = new FileInputStream(sdFile);
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                fileMap.clear();
                videoBurnInList.clear();
                String line;
                //分行读取
                while ((line = br.readLine()) != null) {
                    if (line.contains(":")){
                        String[] strings = line.split(":");
                        fileMap.put(strings[0], strings[1]);
                        Log.d(TAG, "line --->" + line);
                        if (videoBurnInList.size() == 0) videoBurnInList = splitStringPath(strings[1]);
                        bw.write(line + "\n");
                        bw.flush();
                    }
                }
                br.close();
                isr.close();
                is.close();

                bw.close();
                osw.close();
                os.close();
                ToastUtil.toast("Video resources are updated.");
            } catch (IOException e) {
                Log.d(TAG, e.getMessage());
            }


            boolean b2 = sdFile.delete();
            if (b2) {
                Log.d(TAG, "delete is ok");
            } else {
                Log.d(TAG, "delete is error");
                String cmd = "rm -rf " + titlePath + "codeValue.txt";
                boolean b1 = exeC(cmd);
                if (b1) {
                    Log.d(TAG, "exeC delete is ok");
                } else {
                    Log.d(TAG, "exeC delete is error");
                }

            }

            Log.d(TAG, titlePath + " File is exists---?" + sdFile.exists());
        } else readTxtFile(localFilePath);
    }

    private boolean exeC(String command) {
        Process process = null;
        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec("su");
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(command + "\n");
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
        } catch (Exception e) {
            return false;
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (process != null) {
                    process.destroy();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    public void readTxtFile(final String filePath) {

        //打开文件
        if (filePath == null) return;
        File file = new File(filePath);
        if (file.exists()) {
            try {
                InputStream instream = new FileInputStream(file);
                InputStreamReader inputreader = new InputStreamReader(instream);
                BufferedReader buffreader = new BufferedReader(inputreader);
                String line;
                fileMap.clear();
                videoBurnInList.clear();
                //分行读取
                while ((line = buffreader.readLine()) != null) {
                    if (line.contains(":")){
                        String[] strings = line.split(":");
                        fileMap.put(strings[0], strings[1]);
                        if (videoBurnInList.size() == 0) videoBurnInList = splitStringPath(strings[1]);

                    }
                }
                instream.close();

            } catch (java.io.FileNotFoundException e) {
                Log.d(TAG, "The File doesn't not exist.");
            } catch (IOException e) {
                Log.d(TAG, e.getMessage());
            }
        } else {
            ToastUtil.toast("No video profile detected, please check.");
        }

    }

    // 获取次存储卡路径,一般就是外置 TF 卡了. 不过也有可能是 USB OTG 设备...
    public String getSecondaryStoragePath() {
        try {
            StorageManager sm = (StorageManager) MediaApplication.getApplication().getSystemService(STORAGE_SERVICE);
            Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", null);
            String[] paths = (String[]) getVolumePathsMethod.invoke(sm, null);
            // second element in paths[] is secondary storage path
            return paths.length <= 1 ? null : paths[1];
        } catch (Exception e) {
            Log.e("util", "getSecondaryStoragePath() failed", e);
        }
        return null;
    }

    /**
     * 用户权限 申请 的回调方法
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 123) {
            boolean isAllGranted = true;
            for(int result : grantResults){
                if(result == PackageManager.PERMISSION_DENIED){
                    isAllGranted = false;
                    break;
                }
            }
            //获取权限成功
            if (isAllGranted) setTimer();
            //如果没有获取权限，那么可以提示用户去设置界面--->应用权限开启权限
            else ToastUtil.toast("Please go to set the interface opening permission");
        }
    }

    private LinkedList<String> splitStringPath(String value) {

        String[] strings = value.split(";");

        return new LinkedList<>(Arrays.asList(strings));
    }

    private int count = 0;
    private LinkedList<String> videoList = new LinkedList<>();
    private LinkedList<String> videoBurnInList = new LinkedList<>();
    private BroadcastReceiver characteristicReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if ("characteristic".equals(action)) {
                try {
                    Runtime.getRuntime().exec(CommandBean.flashingLight.getCommandString());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String value = fileMap.get(intent.getStringExtra("value"));
                if (value != null) {
                    videoList.clear();
                    count = 0;
                    videoList = splitStringPath(value);
                    isPlayBurnInVideo = true;
                    playVideo();
                }

                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mediaPlayer) {
                        Log.d(TAG,"start play");
                        video_view.setBackground(null);
                        mIBinder.setSeekTo(0);
                        mIBinder.startPlay();
                    }
                });
                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mediaPlayer) {
                        nextVideo();
                    }
                });

            }else if ("connect".equals(action)){
                String status = intent.getStringExtra("status");
                if (status.contains("disconnected") || status.contains("fail")) SCAN_AGAIN = 15000;
                else if (status.contains("successful")) SCAN_AGAIN = 30000;
                ToastUtil.toast(intent.getStringExtra("status"));
            }
        }
    };

    private void nextVideo() {
        count++;
        //表示已经全部播放完毕,让count变成0即可
        if (count >= videoList.size()) count = -123;
        if (count != -123) playVideo();
        else {
            video_view.setBackgroundResource(R.drawable.main);
            isPlayBurnInVideo = false;
        }

    }

    private void playVideo() {
        if (videoList == null || videoList.size() == 0) {
            ToastUtil.toast("Sorry, this option allows stateless video to play");
            isPlayBurnInVideo = false;
            return;
        }
        mediaPlayer.reset();
        try {
            mediaPlayer.setDataSource(titlePath + videoList.get(count).trim());
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            if (mGetVideoFileUtil.sdCardExist()) {
                nextVideo();
                ToastUtil.toast("The previous video does not exist, you have to jump to the next video.");
            } else {
                ToastUtil.toast("The memory card is not available.");
            }
        }
    }

    private BluetoothAdapter initBluetoothAdapter() {
        BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
        return mBluetoothManager.getAdapter();
    }

    /**
     * 检查权限
     */
    private boolean isAdapterEnabled() {
        return BluetoothAdapter.getDefaultAdapter().isEnabled();
    }

    private BluetoothAdapter mBluetoothAdapter;
    private Runnable scannable;
    private Handler handler = new Handler();
    private long SCAN_AGAIN = 15000;
    private ScanCallback scanCallback = new ScanCallback();

    private void scanDevice() {
        if (scannable != null)
            handler.removeCallbacks(scannable);

        long SCAN_TIME = 5000;
        if (isAdapterEnabled()) {
            mBluetoothAdapter.startLeScan(scanCallback);
            scannable = new Runnable() {
                @Override
                public void run() {
                    stopScanDevice();
                }
            };
            handler.postDelayed(scannable, SCAN_TIME);
        }else {
            mBluetoothAdapter.enable();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    scanDevice();
                }
            }, SCAN_TIME);
        }
    }

    private ScheduledExecutorService executorService;

    private void setTimer() {
        executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                mHandler.sendEmptyMessage(123);
            }
        }, 0, SCAN_AGAIN, TimeUnit.MILLISECONDS);
    }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 123) {
                scanDevice();
            }
        }
    };

    /**
     * 停止扫描
     */
    private void stopScanDevice() {
        if (scannable != null)
            handler.removeCallbacks(scannable);
        mBluetoothAdapter.stopLeScan(scanCallback);
    }

    static String titlePath;


    private VideoPlayService.MediaControlBinder mIBinder;
    ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mIBinder = (VideoPlayService.MediaControlBinder) iBinder;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };


    private void setNavigationBarVisible(Activity activity, boolean isHide) {
        if (isHide) {
            View decorView = activity.getWindow().getDecorView();
            int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(uiOptions);
        } else {
            View decorView = activity.getWindow().getDecorView();
            int uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
            decorView.setSystemUiVisibility(uiOptions);
        }
    }


    private void initSurfaceView() {
        fileSetting = findViewById(R.id.file_setting);
        fileManage = findViewById(R.id.file_manage);
        setting = findViewById(R.id.setting);
        SurfaceView videoSuf = (SurfaceView) findViewById(R.id.video_view);

        video_view = (VideoView) videoSuf;
        video_view.setBackgroundResource(R.drawable.main);

        videoSuf.setZOrderOnTop(false);
        videoSuf.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        videoSuf.getHolder().addCallback(new SurfaceCallback());
    }


    GetVideoFileUtil mGetVideoFileUtil = new GetVideoFileUtil();

    @Override
    protected void onResume() {
        super.onResume();
        try {

            mediaPlayer.reset();
            String path = "android.resource://" + getPackageName() + "/" + R.raw.bootanimation1;
            mediaPlayer.setDataSource(getApplicationContext(), Uri.parse(path));

            mediaPlayer.setOnBufferingUpdateListener(new MediaPlayerListener());
            //mediaPlayer.prepare();
//            controller.setMediaPlayer(new VideoPlayService());
//            controller.setEnabled(true);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mediaPlayer) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
//        controller.show();
        return super.onTouchEvent(event);
    }
    private Drawable border;
    private Drawable noBorder;
    private boolean isShow(){
        return fileSetting.getVisibility() == View.VISIBLE;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        switch (keyCode) {
            //确定键  OK
            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_DPAD_CENTER:
                if (isShow()){
                    keyEventCount = 0;
                    if (setting.getBackground().equals(border)) gotoSetting();
                    else gotoFileManage();
                }
                break;
            //返回键
            case KeyEvent.KEYCODE_BACK:
                if (isShow()) fileSetting.setVisibility(View.GONE);
                else if (isPlayBurnInVideo){
                    mIBinder.stopPlay();
                    video_view.setBackgroundResource(R.drawable.main);
                    isPlayBurnInVideo = false;
                    mediaPlayer.reset();
                }
                //这里由于break会退出，所以我们自己要处理掉 不返回上一层
                return true;
            //向左键//向右键
            case KeyEvent.KEYCODE_DPAD_LEFT:
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                if (isShow()){
                    keyEventCount = 0;
                    if (setting.getBackground().equals(border)){
                        setting.setBackground(noBorder);
                        fileManage.setBackground(border);
                    }else {
                        fileManage.setBackground(noBorder);
                        setting.setBackground(border);
                    }
                }
                break;
            //菜单键
            case KeyEvent.KEYCODE_MENU:
                keyEventCount = 0;
                if (!isShow()) fileSetting.setVisibility(View.VISIBLE);
                break;
            //向下键
            case KeyEvent.KEYCODE_DPAD_DOWN:
                if (!isShow()) break;
                Log.d(TAG,"down   keyEventCount--->" + keyEventCount);
                if (keyEventCount%2==1){
                    if (keyEventCount == 5){
                        isPlayBurnInVideo = true;
                        fileSetting.setVisibility(View.GONE);
                        playBurnInVideo();
                    }
                    else keyEventCount++;
                }
                break;
            //向上键
            case KeyEvent.KEYCODE_DPAD_UP:
                if (!isShow()) break;
                Log.d(TAG,"up   keyEventCount--->" + keyEventCount);
                if (keyEventCount%2==0) keyEventCount++;
                break;
            default:
                Log.d(TAG,"default event ---->" + event);
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    private void nextBurnInVideo() {
        count++;
        //表示已经全部播放完毕,让count变成0即可
        if (count >= videoBurnInList.size()) count = 0;
        playBurnInVideo();
    }

    private void playBurnInVideo() {
        if (videoBurnInList == null || videoBurnInList.size() == 0) {
            ToastUtil.toast("Sorry, this option allows stateless video to play");
            return;
        }
        mediaPlayer.reset();
        try {
            mediaPlayer.setDataSource(titlePath + videoBurnInList.get(count).trim());
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(mPreparedListener);
            mediaPlayer.setOnCompletionListener(mCompletionListener);
        } catch (IOException e) {
            if (mGetVideoFileUtil.sdCardExist()) {
                nextBurnInVideo();
                ToastUtil.toast("The previous video does not exist, you have to jump to the next video.");
            } else {
                ToastUtil.toast("The memory card is not available.");
            }
        }
    }

    private int keyEventCount;
    private boolean isPlayBurnInVideo;
    private MediaPlayer.OnPreparedListener mPreparedListener =
            new MediaPlayer.OnPreparedListener() {

                @Override
                public void onPrepared(MediaPlayer mp) {
                    video_view.setBackground(null);
                    mp.start();
                }
            };

    private MediaPlayer.OnCompletionListener mCompletionListener =
            new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    nextBurnInVideo();
                }
            };

    public void gotoSetting() {
        //调用系统WIFI界面
        Intent wifiSettingsIntent = new Intent("android.settings.WIFI_SETTINGS");
        startActivity(wifiSettingsIntent);

    }
    public void gotoFileManage() {
        //调用系统文件管理器打开指定路径目录
        /*Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("video/*");*/
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        ComponentName cn = new ComponentName("com.android.rockchip", "com.android.rockchip.RockExplorer");
        intent.setComponent(cn);
        startActivityForResult(intent, READ_REQUEST_CODE);

    }
    private int READ_REQUEST_CODE = 61;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

        if (resultCode == Activity.RESULT_OK){
            Uri uri = null;

            if (data != null) {
                uri = data.getData();
            }
            Log.d(TAG,"request uri is --->" + uri);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }


}